package com.hjw.dynamicdatasource.controller;

import com.hjw.dynamicdatasource.util.DatabaseMetadataUtil;
import com.hjw.dynamicdatasource.service.DynamicService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 动态数据控制器，提供动态实体类和CRUD操作的REST接口
 */
@Slf4j
@RestController
@RequestMapping("/dynamic")
public class DynamicDataController {

    @Autowired
    private DynamicService dynamicService;
    
    /**
     * 获取数据库中所有表的结构信息
     * @param schema 数据库模式（可选）
     * @return 表结构信息列表
     */
    @GetMapping("/tables")
    public List<DatabaseMetadataUtil.TableInfo> getTables(@RequestParam(required = false) String schema) {
        try {
            return dynamicService.getDatabaseTables(schema);
        } catch (Exception e) {
            log.error("获取表结构失败", e);
            throw new RuntimeException("获取表结构失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取指定表的结构信息
     * @param tableName 表名
     * @param schema 数据库模式（可选）
     * @return 表结构信息
     */
    @GetMapping("/tables/{tableName}")
    public DatabaseMetadataUtil.TableInfo getTable(@PathVariable String tableName, 
                                                 @RequestParam(required = false) String schema) {
        try {
            List<DatabaseMetadataUtil.TableInfo> tables = dynamicService.getDatabaseTables(schema);
            for (DatabaseMetadataUtil.TableInfo table : tables) {
                if (table.getTableName().equalsIgnoreCase(tableName)) {
                    return table;
                }
            }
            throw new IllegalArgumentException("表不存在: " + tableName);
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取表结构失败", e);
            throw new RuntimeException("获取表结构失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询表中的所有数据
     * @param tableName 表名
     * @param schema 数据库模式（可选）
     * @return 数据列表
     */
    @GetMapping("/data/{tableName}")
    public List<Map<String, Object>> findAll(@PathVariable String tableName, 
                                            @RequestParam(required = false) String schema) {
        try {
            return dynamicService.findAll(tableName, schema);
        } catch (Exception e) {
            log.error("查询数据失败", e);
            throw new RuntimeException("查询数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 根据ID查询数据
     * @param tableName 表名
     * @param id ID值
     * @param schema 数据库模式（可选）
     * @return 数据Map
     */
    @GetMapping("/data/{tableName}/{id}")
    public Map<String, Object> findById(@PathVariable String tableName, 
                                       @PathVariable String id, 
                                       @RequestParam(required = false) String schema) {
        Map<String, Object> result = null;

        try {
            result = dynamicService.findById(tableName, id, schema);
            return result;
        } catch (Exception e) {
            log.error("查询数据失败: {}", e.getMessage());
            result = new HashMap<>(3);
            result.put("success", false);
            result.put("message", e.getMessage());
            result.put("data", e);
            return result;

        }
    }
    
    /**
     * 插入数据
     * @param tableName 表名
     * @param data 数据Map
     * @param schema 数据库模式（可选）
     * @return 插入结果
     */
    @PostMapping("/data/{tableName}")
    public Result insert(@PathVariable String tableName, 
                        @RequestBody Map<String, Object> data, 
                        @RequestParam(required = false) String schema) {
        try {
            boolean success = dynamicService.insert(tableName, data, schema);
            return new Result(success, success ? "插入成功" : "插入失败");
        } catch (Exception e) {
            log.error("插入数据失败", e);
            return new Result(false, "插入失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新数据
     * @param tableName 表名
     * @param id ID值
     * @param data 数据Map
     * @param schema 数据库模式（可选）
     * @return 更新结果
     */
    @PutMapping("/data/{tableName}/{id}")
    public Result update(@PathVariable String tableName, 
                        @PathVariable String id, 
                        @RequestBody Map<String, Object> data, 
                        @RequestParam(required = false) String schema) {
        try {
            boolean success = dynamicService.update(tableName, id, data, schema);
            return new Result(success, success ? "更新成功" : "更新失败：数据不存在");
        } catch (Exception e) {
            log.error("更新数据失败", e);
            return new Result(false, "更新失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除数据
     * @param tableName 表名
     * @param id ID值
     * @param schema 数据库模式（可选）
     * @return 删除结果
     */
    @DeleteMapping("/data/{tableName}/{id}")
    public Result delete(@PathVariable String tableName, 
                        @PathVariable String id, 
                        @RequestParam(required = false) String schema) {
        try {
            boolean success = dynamicService.delete(tableName, id, schema);
            return new Result(success, success ? "删除成功" : "删除失败：数据不存在");
        } catch (Exception e) {
            log.error("删除数据失败", e);
            return new Result(false, "删除失败: " + e.getMessage());
        }
    }
    
    /**
     * 执行自定义SQL查询
     * @param sqlRequest SQL请求
     * @return 查询结果列表
     */
    @PostMapping("/sql")
    public List<Map<String, Object>> executeSql(@RequestBody SqlRequest sqlRequest) {
        try {
            return dynamicService.executeSql(
                    sqlRequest.getSql(), 
                    sqlRequest.getParams(), 
                    sqlRequest.getTableName(), 
                    sqlRequest.getSchema()
            );
        } catch (Exception e) {
            log.error("执行SQL失败", e);
            throw new RuntimeException("执行SQL失败: " + e.getMessage());
        }
    }
    
    /**
     * 清除缓存
     * @return 操作结果
     */
    @PostMapping("/clear-cache")
    public Result clearCache() {
        try {
            dynamicService.clearCache();
            return new Result(true, "缓存清除成功");
        } catch (Exception e) {
            log.error("清除缓存失败", e);
            return new Result(false, "清除缓存失败: " + e.getMessage());
        }
    }
    
    /**
     * 通用结果类
     */
    @Data
    public static class Result {
        private boolean success;
        private String message;
        
        public Result(boolean success, String message) {
            this.success = success;
            this.message = message;
        }
    }
    
    /**
     * SQL请求类
     */
    @Data
    public static class SqlRequest {
        private String sql;
        private Map<String, Object> params;
        private String tableName;
        private String schema;
    }
}